import { Component, Vue } from 'vue-property-decorator';
import style from '@/styles/views/gas.module.less';
import { EapLayout, Window } from '@/components';
import { Button, Cell, CellGroup, Dialog, Icon, NavBar, PullRefresh, Radio, RadioGroup, Slider, SwipeCell } from 'vant';
import { IDevice } from '@/interfaces/api.interface';
import _ from 'lodash';

interface IInitData {
  window_percent: number;
}

enum EDeviceType {
  'gas.ch2o',
  'gas.ch4',
  'gas.co',
  'gas.c2h5oh',
  'gas.tvoc',
  'device.window'
}

const GAS_VALUE_RANGE = {
  // 气体取值区间
  co: [0, 500],
  ch2o: [0, 3],
  c2h5oh: [0, 300],
  tvoc: [0, 20],
  ch4: [0, 10000]
};

const GAS_DEFAULT_ALARM_VALUES = { // 气体检测默认警告值
  'co': 100,
  // 'ch2o': 0.06,
  'ch2o': 0.01,
  'c2h5oh': 50,
  'tvoc': 0.5,
  'ch4': 3000
}

type IGasType = 'co' | 'ch2o' | 'c2h5oh' | 'tvoc' | 'ch4';

interface ISceneDevice extends IDevice {
  real_value: number;
  alarm_value?: number;
}

Vue.use(Dialog);

@Component({
  components: {
    window: Window,
    'eap-layout': EapLayout,
    'van-nav-bar': NavBar,
    'van-button': Button,
    'van-radio-group': RadioGroup,
    'van-radio': Radio,
    'van-cell-group': CellGroup,
    'van-cell': Cell,
    'van-slider': Slider,
    'van-swipe-cell': SwipeCell,
    'van-pull-refresh': PullRefresh,
    'van-icon': Icon
  },
  sockets: {
    connect() {
      // 说明是断线重连
      this.$socket.client.emit('init', (data: IInitData) => {
        this.$data.window_percent = data.window_percent;
      });
    },
    devices(data) {
      this.$data.devices = data;
    },
    message({ devid, data }) {
      const dev = this.$data.sceneDeviceMap.get(devid);
      if (!dev) return;
      this.$data.sceneDeviceMap.set(devid, { ...dev, real_value: data });
      this.$forceUpdate();
      if (dev.report.type === 'device.window') {
        this.$data.windowDevice = { ...dev, real_value: data };
      }
    },
    join(dev: ISceneDevice) {
      this.$data.sceneDeviceMap.set(dev.devid, dev);
      this.$forceUpdate();
      if (dev.report.type === 'device.window') {
        this.$data.windowDevice = dev;
      }
    },
    lost(dev) {
      this.$edger.notify.error(`${dev.alias}设备丢失！`);
      this.$data.sceneDeviceMap.delete(dev.devid);
      this.$forceUpdate();
      if (dev.report.type === 'device.window') {
        this.$data.windowDevice = null;
      }
    },
    delete(dev) {
      this.$data.sceneDeviceMap.delete(dev.devid);
      this.$forceUpdate();
      if (dev.report.type === 'device.window') {
        this.$data.windowDevice = null;
      }
    },
    alarm({ devid, value }) {
      const dev = this.$data.sceneDeviceMap.get(devid);
      if (!dev) {
        return this.$edger.notify.warning('数据可能出错，请刷新页面！');
      }
      this.$data.sceneDeviceMap.set(devid, { ...dev, alarm_value: value });
    },
    error(msg) {
      this.$edger.notify.error(msg);
    },
    success(msg) {
      this.$edger.notify.success(msg);
    }
  }
})
export default class Gas extends Vue {
  private showModel = false;
  private alarmModel: { show: boolean; alias: string; alarm_value: number; devid: string; type: IGasType } = {
    show: false,
    alias: '',
    devid: '',
    type: 'c2h5oh',
    alarm_value: 0
  };
  private devices: IDevice[] = [];
  private sceneDeviceMap: Map<string, ISceneDevice> = new Map([]);
  private windowDevice: ISceneDevice | null = null;
  private isReload = false;

  public created() {
    this.$socket.client.emit('init', (data: IInitData) => {
      console.log(data);
    });
  }

  public render() {
    return (
      <van-pull-refresh
        v-model={this.isReload}
        loading-text='正在同步场景数据...'
        disabled={this.showModel || this.alarmModel.show}
        on-refresh={this.handleRefresh}>
        <eap-layout>
          <van-nav-bar title='智能窗户' />
          <div class={style['gas']}>
            <div class={style['gas-window']}>
              <window
                value={this.windowDevice ? this.windowDevice!.real_value : 0}
                disabled={!this.windowDevice}
                on-slide={this.handleSlide}></window>
            </div>
            <h3>
              设备列表
              <van-button
                type='primary'
                icon='plus'
                size='mini'
                class={style['gas-add']}
                on-click={() => {
                  this.showModel = true;
                }}>
                添加
              </van-button>
            </h3>
            {this.renderDevGroup()}
          </div>

          {this.renderDevModel()}
          {/* {this.renderGasDevAlarmModel()} */}
        </eap-layout>
      </van-pull-refresh>
    );
  }

  private renderDevGroup() {
    return (
      <div class={style['gas-group']}>
        {[...this.sceneDeviceMap.values()].map((item: ISceneDevice) => {
          return (
            <van-swipe-cell stop-propagation>
              <div class={style['gas-item-content']}>
                <h5>{item.alias}</h5>
                <span
                  style={{
                    color:
                      item.report.type !== 'device.window' && item.real_value > item.alarm_value!
                        ? '#ee0a24'
                        : '#07c160'
                  }}>
                  {item.report.type === 'device.window' ? (item.real_value > 0 ? '开' : '关') : item.real_value}
                </span>
              </div>
              <template slot='right'>
                {/* {item.report.type !== 'device.window' && (
                  <van-button
                    icon='setting-o'
                    square
                    on-click={() => {
                      this.showAlarmValueModel(item);
                    }}
                  />
                )} */}
                <van-button type='danger' icon='delete-o' square on-click={() => this.deleteDevice(item)} />
              </template>
            </van-swipe-cell>
          );
        })}
      </div>
    );
  }

  private renderDevModel() {
    return (
      <van-dialog
        v-model={this.showModel}
        title='选择设备'
        showConfirmButton={false}
        closeOnClickOverlay
        class={style['model']}>
        <div class={style['model-list']}>{this.renderSelectDevList()}</div>
      </van-dialog>
    );
  }

  // private renderGasDevAlarmModel() {
  //   return (
  //     <van-dialog
  //       v-model={this.alarmModel.show}
  //       title={`设置${this.alarmModel.alias}警告值`}
  //       showConfirmButton={false}
  //       closeOnClickOverlay
  //       class={style['model-alarm']}>
  //       <div class={style['model-alarm-slider-group']}>
  //         <div class={[style['model-alarm-slider']]}>
  //           <van-slider
  //             v-model={this.alarmModel.alarm_value}
  //             active-color='#ee0a24'
  //             max={GAS_VALUE_RANGE[this.alarmModel.type][1]}
  //             min={GAS_VALUE_RANGE[this.alarmModel.type][0]}
  //             on-drag-end={() => this.changeAlarm()}>
  //             <template slot='button'>
  //               <div class={style['custom-button']}>{this.alarmModel.alarm_value}</div>
  //             </template>
  //           </van-slider>
  //         </div>
  //       </div>
  //     </van-dialog>
  //   );
  // }

  private renderSelectDevList() {
    return (
      <van-radio-group>
        <van-cell-group>
          {this.devices.map((item: IDevice) => {
            return (
              <van-cell
                title={item.alias}
                clickable
                style={{ color: item.join ? '#666' : '#ccc' }}
                on-click={() => {
                  this.addDevice(item);
                }}>
                {/* <van-radio name={item.devid} slot='right-icon' /> */}
                {/* <van-icon name='circle' color='#ccc' size={24} slot='right-icon' /> */}
                {item.join && this.sceneDeviceMap.has(item.devid) && (
                  <van-icon name='success' color='#07c160' size={24} slot='right-icon' />
                )}
                {/* {item.join && !this.sceneDeviceMap.has(item.devid) && <van-icon name='warn-o' slot='right-icon' />} */}
              </van-cell>
            );
          })}
        </van-cell-group>
      </van-radio-group>
    );
  }

  // 选择场景设备
  private async addDevice(dev: IDevice) {
    if (!dev.join) {
      return;
    }
    if (this.sceneDeviceMap.has(dev.devid)) {
      return; // 选中设备为当前已选设备
    }
    if (!this.checkDeviceType(dev)) {
      // 这里目前只有一个窗户
      return this.$edger.notify.warning('请选择正确类型和型号的设备！');
    }
    this.$socket.client.emit('add-scene-device', dev.devid);
    this.showModel = false;
  }

  // 删除场景设备
  private async deleteDevice(dev: IDevice) {
    this.$socket.client.emit('delete-scene-device', dev.devid);
  }

  // 显示气体设备设置警告值模态框
  private showAlarmValueModel(dev: ISceneDevice) {
    const type = this.getDeviceType(dev) as IGasType;
    this.alarmModel = {
      show: true,
      devid: dev.devid,
      alias: dev.alias,
      type,
      alarm_value: dev.alarm_value!
    };
  }

  private handleSlide(status: 'left' | 'right' | 'OFF') {
    this.$socket.client.emit('send-device-message', {
      devid: this.windowDevice?.devid,
      data: { method: 'set', window: status }
    });
  }

  private changeAlarm() {
    const data: any = {
      method: 'set'
    };
    const { devid, alarm_value } = this.alarmModel;
    const dev = this.sceneDeviceMap.get(devid);
    if (!dev) {
      return;
    }
    const type = this.getDeviceType(dev);
    switch (type) {
      case 'tvoc':
        data.tvoc = alarm_value;
        break;
      case 'co':
        data.co = alarm_value;
        break;
      case 'ch4':
        data.ch4 = alarm_value;
        break;
      case 'c2h5oh':
        data.c2h5oh = alarm_value;
        break;
      case 'ch2o':
        data.ch2o = alarm_value;
        break;
      default:
        return this.$edger.notify.error('程序出现未知错误, 请重试！');
    }
    this.$socket.client.emit('send-device-message', {
      devid,
      data
    });
  }

  private checkDeviceType(dev: IDevice) {
    const {
      report: { type, model }
    } = dev;
    if (type === 'gas.co' && model === 'IDCO01B') return true;
    if (type === 'gas.ch2o' && model === 'IDCH2O01B') return true;
    if (type === 'gas.c2h5oh' && model === 'IDC2H5OH01B') return true;
    if (type === 'gas.tvoc' && model === 'IDTVOC01B') return true;
    if (type === 'gas.ch4' && model === 'IDCH401B') return true;
    if (type === 'device.window' && model === 'IDWINDOW01B') return true;
    return false;
  }

  private getDeviceType(dev: ISceneDevice) {
    const {
      report: { type, model }
    } = dev || {};
    if (type === 'device.window' && model === 'IDWINDOW01B') {
      return 'window';
    }
    if (type === 'gas.co' && model === 'IDCO01B') {
      return 'co';
    }
    if (type === 'gas.ch2o' && model === 'IDCH2O01B') {
      return 'ch2o';
    }
    if (type === 'gas.c2h5oh' && model === 'IDC2H5OH01B') {
      return 'c2h5oh';
    }
    if (type === 'gas.tvoc' && model === 'IDTVOC01B') {
      return 'tvoc';
    }
    if (type === 'gas.ch4' && model === 'IDCH401B') {
      return 'ch4';
    }
  }

  private handleRefresh() {
    let t: number | undefined = 0;
    t = setTimeout(() => {
      this.$edger.notify.error('同步数据失败, 请重试！');
    }, 5000);
    this.$socket.client.emit('init', () => {
      this.isReload = false;
      clearTimeout(t);
      t = undefined;
    });
  }
}
